import random
from datetime import datetime

from flask import request, abort, current_app, make_response, Response, jsonify, session
from info import sr, db
from info.libs.yuntongxun.sms import CCP
# from info.models import User
from info.models import User

from info.modules.passport import passport_blu
from info.constants import IMAGE_CODE_REDIS_EXPIRES, SMS_CODE_REDIS_EXPIRES
from info.libs.captcha.pic_captcha import captcha
from info.utils.response_code import error_map, RET
import re

# 获取图片验证码
@passport_blu.route('/get_img_code')
def get_img_code():
    # 获取参数
    img_code_id = request.args.get("img_code_id")
    print(img_code_id)
    # 校验参数
    if not img_code_id:
        return abort(403)  # 403表示拒绝访问

    # 生成图片验证码
    img_name, img_text, img_bytes = captcha.generate_captcha()
    print(img_text)

    # 保存验证码文字和图片key   Redis保存  方便设置过期时间, 键值关系也满足需求
    try:
        sr.set("img_code_id_" + img_code_id, img_text, ex=IMAGE_CODE_REDIS_EXPIRES)
    except BaseException as e:
        current_app.logger.error(e)  # 记录日志
        return abort(500)

    # 返回图片  为了设置content-type,自定义响应对象
    response = make_response(img_bytes)  # type: Response
    response.content_type = "image/jpeg"
    return response


#短信验证码
@passport_blu.route('/get_sms_code',methods=['POST'])
def get_sms_code():
    # 获取参数
    img_code_id = request.json.get("img_code_id")
    img_code = request.json.get("img_code")
    mobile = request.json.get("mobile")
    # 校验参数
    if not all([img_code_id, img_code, mobile]):
        # 返回错误代码及对应的错误信息
        return jsonify(errmsg=error_map[RET.PARAMERR], errno=RET.PARAMERR)

    # 校验手机号格式
    if not re.match(r"1[345678]\d{9}$", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 校验图片验证码  根据图片key取出正确的图片验证码
    try:
        real_img_code = sr.get("img_code_id_" + img_code_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    if real_img_code != img_code.upper():  # 验证码错误
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    try:
        user=User.query.filter_by(mobile=mobile).first()
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    if user:  #用户已存在
        return jsonify(errno=RET.DATAEXIST, errmsg=error_map[RET.DATAEXIST])

    #生成随机验证码
    rand_num="%04d"%random.randint(0,9999)
    print(rand_num)
    # 发送短信
    # reponse_code=CCP().send_template_sms(mobile,[rand_num,SMS_CODE_REDIS_EXPIRES],1)
    # if reponse_code != 0:  #发送短信失败
    #     return jsonify(errno=RET.THIRDERR,errmsg7=error_map[RET.THIRDERR])

    # 保存短信验证码
    try:
        sr.set("sms_code_id_"+mobile,rand_num,ex=SMS_CODE_REDIS_EXPIRES)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg=error_map[RET.DBERR])

    #控制台打印验证吗
    current_app.logger.info("验证码:%s"%rand_num)

    # 返回json结果
    return jsonify(errno=RET.OK,errmsg=error_map[RET.OK])


#用户注册
@passport_blu.route('/register',methods=['POST'])
def register():
    #获取参数
    mobile = request.json.get("mobile")
    password=request.json.get("password")
    sms_code=request.json.get("sms_code")
    #校验参数
    if not all([mobile,password,sms_code]):
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    # 校验手机号格式
    if not re.match(r"1[345678]\d{9}$", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 验证短信验证码  根据手机号取出验证码
    try:
        real_sms_code = sr.get("sms_code_id_" + mobile)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    if real_sms_code != sms_code:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    #保存用户数据
    user=User()
    user.mobile=mobile
    # 対password进行加密
    user.password=password
    user.nick_name=mobile
    db.session.add(user)
    try:
        db.session.commit()
    except BaseException as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg=error_map[RET.DBERR])
    #注册/登录成功后,进行状态保持
    session["user_id"]=user.id
    #返回json结果
    return jsonify(errno=RET.OK,errmsg=error_map[RET.OK])

#用户登录
@passport_blu.route('/login',methods=['POST'])
def login():
    #获取参数
    mobile=request.json.get("mobile")
    password=request.json.get("password")
    #校验参数
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 校验手机格式
    if not re.match(r"1[345678]]\d{9}$",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    #取出用户数据  根据手机号
    try:
        user=User.query.filter_by(mobile=mobile).first()
    except BaseException as e:
        current_app.logger.erro(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    #判断用户是否存在
    if not user:
        return jsonify(errno=RET.USERERR,errmsg=error_map[RET.USERERR])
    #校验密码:
    if not user.check_password(password):
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])

    #状态保持
    session["user_id"]=user.id

    #记录最后登录时间,获取当前的日期对象
    user.last_login=datetime.now()

    # 返回json数据
    return jsonify(errno=RET.OK,errmsg=error_map[RET.OK])





